cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(AMCAXInterop)

# Check glibc version
set(USE_CONAN ON)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  include(${CMAKE_SOURCE_DIR}/cmake/check_glibc_version.cmake)
  set(REQUIRED_GLIBC_VERSION 234) # 表示 2.28
  get_glibc_version()
  
  if(${CURRENT_GLIBC_VERSION} LESS ${REQUIRED_GLIBC_VERSION})
    set(USE_CONAN OFF)
  endif()
  message(USE_CONAN -> ${USE_CONAN})
endif()


if(WIN32)
  add_compile_options("/std:c++17")
  add_compile_definitions(_USE_MATH_DEFINES)
endif()

include_directories(${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_SOURCE_DIR}/include)

if (NOT DEFINED CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Debug)
endif()
# 3rd
set(CONAN_DIR ${CMAKE_SOURCE_DIR}/.conan/${CMAKE_BUILD_TYPE})
include(${CONAN_DIR}/conan_toolchain.cmake)

# spdlog
find_package(spdlog REQUIRED)
list(APPEND CONAN_PRIVATE_LIBRARIES spdlog::spdlog)

find_package(threadpool REQUIRED)
list(APPEND CONAN_PRIVATE_LIBRARIES threadpool::threadpool)

# nlohmann_json
find_package(nlohmann_json REQUIRED)
list(APPEND CONAN_PRIVATE_LIBRARIES nlohmann_json::nlohmann_json)

# kernel
if(${USE_CONAN})
  message(STATUS "use conan")
  find_package(AMCAXCommon REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXCommon)

  find_package(AMCAXPart REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXPart)

  find_package(AMCAXOCCTIO REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXOCCTIO)
else()
  message(STATUS "not use conan")
  if(DEFINED ENV{AMCAX_PATH})
    set(3rd $ENV{AMCAX_PATH})
  else()
    set(3rd ${CMAKE_SOURCE_DIR}/3rd)
  endif()
  
  
  set(AMCAXCOMMON_DIR ${3rd}/AMCAXCommon)
  set(AMCAXPART_DIR ${3rd}/AMCAXPart)
  message(status AMCAX:${AMCAXCOMMON_DIR})
  include_directories(${AMCAXCOMMON_DIR}/include)
  include_directories(${AMCAXPART_DIR}/include)
  link_directories(${AMCAXCOMMON_DIR}/lib)
  link_directories(${AMCAXPART_DIR}/lib)
  list(APPEND PUBLIC_LIBRARIES AMCAXCommon)
  list(APPEND PUBLIC_LIBRARIES AMCAXPart)
  list(APPEND PUBLIC_LIBRARIES AMCAXOCCTIO)
  file(GLOB DEPENDLIST ${AMCAXCOMMON_DIR}/lib/*.so)
  list(APPEND LIBRARIES_DIR ${DEPENDLIST})
  file(GLOB DEPENDLIST ${AMCAXPART_DIR}/lib/*.so)
  list(APPEND LIBRARIES_DIR ${DEPENDLIST})
endif()


set(ARCH win_b64)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  set(ARCH linux_a64)
endif()

# interOp
set(ACIS_KERNEL_ROOT_PATH $ENV{ACIS_ROOT})
set(ACIS_KERNEL_INCLUDE_PATH ${ACIS_KERNEL_ROOT_PATH}/include)
set(ACIS_KERNEL_LIB_PATH ${ACIS_KERNEL_ROOT_PATH}/${ARCH}/code/lib)
set(ACIS_KERNEL_BIN_PATH ${ACIS_KERNEL_ROOT_PATH}/${ARCH}/code/bin)

set(INTEROP_ROOT_PATH $ENV{INTEROP_ROOT})
set(INTEROP_INCLUDE_PATH ${INTEROP_ROOT_PATH}/include)
set(INTEROP_LIB_PATH ${INTEROP_ROOT_PATH}/${ARCH}/code/lib)
set(INTEROP_BIN_PATH ${INTEROP_ROOT_PATH}/${ARCH}/code/bin)

# spatial header
include_directories(${ACIS_KERNEL_INCLUDE_PATH})
include_directories(${INTEROP_INCLUDE_PATH})


# set link directories
link_directories(${ACIS_KERNEL_LIB_PATH})
link_directories(${ACIS_KERNEL_BIN_PATH})
link_directories(${INTEROP_LIB_PATH})
link_directories(${INTEROP_BIN_PATH})

add_definitions(-DSPAACISDS) # FIXME:  the difference between SPAACISDS and SPAACIS


if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
  set(INTEROP_LIB_NAME
      SPAAcisDs
      SPAIAcis
      SPAIInterop
      SPAIop
      SPAIopAcis
      SPAIopAcisC
      SPAIopC
      SPAIopParasolid
      SPAIopParasolidC
      SPAIopSampleUtilities
      SPAIopUtilities
      SPAIParasolid
      SPAIParasolidKernel
      SPAXAcisMeshDS
      SPAXAcisPMIEntitiesDS)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  set(INTEROP_LIB_NAME
    SPAIop
    SPAIopAcis
    SPAIopSampleUtilities
  )
endif()

# build lib
message(STATUS "build dynamic library")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
file(GLOB_RECURSE PROJECT_SRC src/*.cpp)
add_library(${PROJECT_NAME} SHARED ${PROJECT_SRC})

target_link_libraries(${PROJECT_NAME} PRIVATE ${CONAN_PRIVATE_LIBRARIES})
target_link_libraries(${PROJECT_NAME} PUBLIC ${INTEROP_LIB_NAME})
target_link_libraries(${PROJECT_NAME} PUBLIC ${PUBLIC_LIBRARIES})

if(NOT ${USE_CONAN})
  target_link_libraries(${PROJECT_NAME} PUBLIC )
endif()

# if(${USE_CONAN})
#   target_link_libraries(${PROJECT_NAME} PUBLIC ${AMCAX_KERNEL_LIBS})
# endif()



# add flags
if(DEBUG_READ_FACE STREQUAL "on")
  add_definitions(-DDEBUG_READ_FACE_ENABLE)
endif()

# build test
include_directories(${CMAKE_SOURCE_DIR}/test)

if(TEST_SAMPLES)
  add_definitions(-DTEST_SAMPLES)
  include(${CMAKE_SOURCE_DIR}/test/samples/uconnectacis/CMakeLists.txt)
    add_executable(TestAMCAXInterop test/main.cpp test/suite/test_interop_samples.cpp ${INTEROP_SAMPLES_SRC})
else()
  file(GLOB_RECURSE TEST_SRC test/*.cpp)
  foreach(file IN LISTS TEST_SRC)
    if(file MATCHES "samples")
      list(REMOVE_ITEM TEST_SRC ${file})
    endif()
  endforeach()
  add_executable(TestAMCAXInterop ${TEST_SRC})
endif()

if(WIN32)
  target_link_libraries(TestAMCAXInterop ${PROJECT_NAME} ${AMCAX_KERNEL_LIBS})
else()
  target_link_libraries(TestAMCAXInterop ${PROJECT_NAME} ${AMCAX_KERNEL_LIBS} )

  if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
      message(STATUS "GCC version: ${CMAKE_CXX_COMPILER_VERSION}")

      if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.4)
          
          add_definitions(-DCXX_LESS_17)
      else()
          target_link_libraries(TestAMCAXInterop stdc++fs )
      endif()
  endif()

endif()

target_include_directories(
  ${PROJECT_NAME}
  PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> # 构建时的包含路径
         $<INSTALL_INTERFACE:include> # 安装后的包含路径
)

# copy share lib into CMAKE_CURRENT_BINARY_DIR
include(${CMAKE_SOURCE_DIR}/cmake/copy_conan_libs.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/get_conan_lib_dirs.cmake)
copy_conan_libs(${CMAKE_CURRENT_BINARY_DIR})

message(USE_CONAN1 -> ${USE_CONAN})
if(NOT ${USE_CONAN})
  message (LIBRARIES_DIR -> ${LIBRARIES_DIR})
  foreach(dir IN LISTS LIBRARIES_DIR)
    message(dir -> ${dir})
    file(COPY ${dir} DESTINATION ${PROJECT_BINARY_DIR}/lib)
  endforeach()

  install(FILES ${LIBRARIES_DIR}
    DESTINATION lib)
endif()


set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/install/${CMAKE_BUILD_TYPE})
install(
    TARGETS ${PROJECT_NAME}
    EXPORT ${PROJECT_NAME}Targets
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin
    INCLUDES DESTINATION  include
    )
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ 
    DESTINATION include)
if(DEFINED ENV{INTEROP_LIBRARY_ZIP_DIR})
  message(STATUS "use env INTEROP_LIBRARY_ZIP_DIR")
  install(FILES $ENV{INTEROP_LIBRARY_ZIP_DIR}/3rd.tar.xz 
  DESTINATION ${CMAKE_INSTALL_PREFIX})  
else()
  message(STATUS "use inner INTEROP_LIBRARY_ZIP_DIR")
  install(FILES ${CMAKE_SOURCE_DIR}/3rd/3rd.tar.xz 
  DESTINATION ${CMAKE_INSTALL_PREFIX})
endif()



set(MY_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Build type")
install(SCRIPT ${CMAKE_SOURCE_DIR}/cmake/extract_tar_xz.cmake)

